package com.pybox.service;

import com.pybox.common.utils.JdbcTemplateUtils;
import com.pybox.dto.TObjectsDto;
import com.pybox.entity.TChangNameDan;
import com.pybox.entity.TObjects;
import com.pybox.repository.TChangNameDanRepository;
import com.pybox.repository.TModelsRepository;
import com.pybox.util.UserUtils;
import org.activiti.engine.*;
import org.activiti.engine.impl.identity.Authentication;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * @author LeiYang
 * @title: TGetShouQuanDanService
 * @projectName pybox
 * @description: 授权码申请单service接口
 * @date 2019/8/517:14
 */
@Service
@Transactional
public class TGetShouQuanDanService {
    @Autowired
    private TChangNameDanRepository tChangNameDanRepository;

    @Autowired
    private TModelsRepository tModelsRepository;

    @Autowired
    private JdbcTemplateUtils jdbcTemplateUtils;

    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private FormService formService;
    @Autowired
    private HistoryService historyService;

    @Autowired
    private TObjectsService tObjectsService;

    /*保存授权申请单*/
    public void save(TChangNameDan dto) {
        if(dto.getObject_id()>0){
            dto.setUserId(UserUtils.getCurrentUser().getId());
            dto.setUsername(UserUtils.getCurrentUser().getRealname());
            dto.setT_status(1);  //表示是审核中
            dto.setType(1); //表示是授权码申请单
            dto.setCtime(new Date());
            dto = tChangNameDanRepository.save(dto);

            //获取授权码码申请单流程开始
            if(dto.getId()>0 && dto.getType() == 1){
                startWorkflew(dto);
            }
        }
    }

    public Boolean startWorkflew(TChangNameDan dto) {
        //3：使用当前对象获取到流程定义的key（对象的名称就是流程定义的key）
        String key = "TGetShouQuanDan";
        /**
         * 4 使用流程变量设置下一个任务的办理人
         * inputUser是流程变量的名称，
         * 获取的办理人是流程变量的值
         */
        Map<String, Object> variables = new HashMap<>();
        variables.put("userID", dto.getExamineId());//表示惟一用户
        /**
         * 5：	(1)使用流程变量设置字符串（格式：tChangNameDan.id的形式），通过设置，让启动的流程（流程实例）关联业务
         (2)使用正在执行对象表中的一个字段BUSINESS_KEY（Activiti提供的一个字段），让启动的流程（流程实例）关联业务
         */
        //格式：tChangNameDan.id的形式（使用流程变量）
        String objId = key + "." + dto.getId()+"";
        variables.put("objId", objId);
        //6：使用流程定义的key，启动流程实例，同时设置流程变量，同时向正在执行的执行对象表中的字段BUSINESS_KEY添加业务数据，同时让流程关联业务
        runtimeService.startProcessInstanceByKey(key, objId, variables);
        return true;
    }

    /*根据任务taskId 完成流程，并更新申请单*/
    public Boolean dealDisagree(Integer id, String tasId,Integer type) {

        //获取连线的名称
        String outcome = "默认提交";
        //批注信息
        String message;
        if(type == 0) {
            message = "不同意改名";
        }else{
            message = "不同意下发授权码";
        }
        /**
         * 1：在完成之前，添加一个批注信息，向act_hi_comment表中添加数据，用于记录对当前申请人的一些审核信息
         */
        //使用任务ID，查询任务对象，获取流程流程实例ID
        Task task = taskService.createTaskQuery()//
                .taskId(tasId)//使用任务ID查询
                .singleResult();
        //获取流程实例ID
        String processInstanceId = task.getProcessInstanceId();
        /**
         * 注意：添加批注的时候，由于Activiti底层代码是使用：
         * 		String userId = Authentication.getAuthenticatedUserId();
         CommentEntity comment = new CommentEntity();
         comment.setUserId(userId);
         所有需要从Session中获取当前登录人，作为该任务的办理人（审核人），对应act_hi_comment表中的User_ID的字段，不过不添加审核人，该字段为null
         所以要求，添加配置执行使用Authentication.setAuthenticatedUserId();添加当前任务的审核人
         * */
        Authentication.setAuthenticatedUserId(UserUtils.getUserId().toString());//(保存的用户的Id)
        taskService.addComment(tasId, processInstanceId, message);
        /**
         * 2：如果连线的名称是“默认提交”，那么就不需要设置，如果不是，就需要设置流程变量
         * 在完成任务之前，设置流程变量，按照连线的名称，去完成任务
         流程变量的名称：outcome
         流程变量的值：连线的名称
         */
        Map<String, Object> variables = new HashMap<>();
        if (outcome != null && !outcome.equals("默认提交")) {
            variables.put("outcome", outcome);
        }

        //3：使用任务ID，完成当前人的个人任务，同时设置流程变量
        taskService.complete(tasId, variables);

        /**
         * 5：在完成任务之后，判断流程是否结束
         如果流程结束了，更新改名申请单表的状态从1变成2（审核中-->审核完成）
         */
        ProcessInstance pi = runtimeService.createProcessInstanceQuery()//
                .processInstanceId(processInstanceId)//使用流程实例ID查询
                .singleResult();
        //流程结束了
        if (pi == null) {
            //更新申请单的状态从1变成2（审核中-->审核完成）
            if(type == 0){ //不同意改名执行逻辑
                tChangNameDanRepository.updateTStatus(id, message, null,new Date());

            }
            if(type == 1){ //申请授权码不同意执行逻辑
                //更新申请单
                tChangNameDanRepository.updateTStatus(id, message,null,new Date());
            }

        }
        return true;
    }
}
